package cn.hutool.benchmark;

import cn.hutool.core.bean.BeanUtil;
import lombok.Data;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;

@BenchmarkMode(Mode.AverageTime)//每次执行平均花费时间
@Warmup(iterations = 5, time = 1) //预热5次调用
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 执行5此，每次1秒
@Threads(1) //单线程
@Fork(1) //
@OutputTimeUnit(TimeUnit.NANOSECONDS) // 单位：纳秒
@State(Scope.Benchmark) // 共享域
public class BeanUtilJmh {

	private TestBean testBean;

	@Setup
	public void setup(){
		testBean = new TestBean();
		testBean.setA("1111");
	}

	@Benchmark
	public void getAJmh(){
		testBean.getA();
	}

	@Benchmark
	public void invokeGetJmh() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
		Method getA = TestBean.class.getMethod("getA");
		getA.invoke(testBean);
	}

	@Benchmark
	public void getFieldValueJmh(){
		BeanUtil.getFieldValue(testBean, "a");
	}

	@Benchmark
	public void getPropertyJmh(){
		BeanUtil.getProperty(testBean, "a");
	}

	@Data
	public static class TestBean{
		private String a;
	}
}
